package com.wubo.sec.config;

import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

import com.wubo.common.date.DateUtil;
import com.wubo.common.util.ClassUtils;

/**
 * @author WuBo
 * @CreateDate 2010-8-30
 * @version 1.0.01
 */
public abstract class ConfigUtils {
	
	private static Map<String, Class<?>> typeMap = new HashMap<String, Class<?>>();
	
	static {
		typeMap.put("byte", byte.class);
		typeMap.put("byte[]", byte[].class);
		typeMap.put("boolean", boolean.class);
		typeMap.put("boolean[]", boolean[].class);
		typeMap.put("float", float.class);
		typeMap.put("float[]", float[].class);
		typeMap.put("int", int.class);
		typeMap.put("int[]", int[].class);
		typeMap.put("long", long.class);
		typeMap.put("long[]", long[].class);
		typeMap.put("string", String.class);
		typeMap.put("string[]", String[].class);
		typeMap.put("float", float.class);
		typeMap.put("float[]", float[].class);
		typeMap.put("double", double.class);
		typeMap.put("double[]", double[].class);
		typeMap.put("char", char.class);
		typeMap.put("char[]", char[].class);
		typeMap.put("date", java.util.Date.class);
		typeMap.put("list", java.util.List.class);
		typeMap.put("map", java.util.Map.class);
	}
	
	public static Class<?> getType(String key) throws NotSupportedTypeException {
		if(! typeMap.containsKey(key)){
			throw new NotSupportedTypeException("This type "+key+" has not supported yet!");
		}
		return typeMap.get(key);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T getValue(String value, Class<T> type) throws NotSupportedTypeException {
		if(value == null){
			return null;
		}
		if(type.isArray()){
			String[] values = value.split(",");
			if(int[].class.isAssignableFrom(type)){
				Integer[] temp = new Integer[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Integer(value.toString());
				}
				return (T) temp;
			}else if(String[].class.isAssignableFrom(type)){
				String[] temp = new String[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new String(value.toString());
				}
				return (T) temp;
			}else if(long[].class.isAssignableFrom(type)){
				Long[] temp = new Long[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Long(value.toString());
				}
				return (T) temp;
			}else if(boolean[].class.isAssignableFrom(type)){
				Boolean[] temp = new Boolean[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Boolean(value.toString());
				}
				return (T) temp;
			}else if(double[].class.isAssignableFrom(type)){
				Double[] temp = new Double[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Double(value.toString());
				}
				return (T) temp;
			}else if(char[].class.isAssignableFrom(type)){
				char[] temp = new char[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = value.toString().charAt(0);
				}
				return (T) temp;
			}else if(short[].class.isAssignableFrom(type)){
				Short[] temp = new Short[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Short(value.toString());
				}
				return (T) temp;
			}else if(float[].class.isAssignableFrom(type)){
				Float[] temp = new Float[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Float(value.toString());
				}
				return (T) temp;
			}else if(byte[].class.isAssignableFrom(type)){
				Byte[] temp = new Byte[values.length];
				for(int i=0; i<values.length; i++){
					temp[i] = new Byte(value.toString());
				}
				return (T) temp;
			}
		}else{
			if(ClassUtils.isPrimitiveWrapper(type)){
				type = ClassUtils.resolvePrimitiveClassName(type);
			}
			if(int.class.isAssignableFrom(type)){
				return (T) new Integer(value.toString());
			}else if(long.class.isAssignableFrom(type)){
				return (T) new Long(value.toString());
			}else if(boolean.class.isAssignableFrom(type)){
				return (T) new Boolean(value.toString());
			}else if(double.class.isAssignableFrom(type)){
				return (T) new Double(value.toString());
			}else if(char.class.isAssignableFrom(type)){
				return (T) (Character) value.toString().charAt(0);
			}else if(short.class.isAssignableFrom(type)){
				return (T) new Short(value.toString());
			}else if(float.class.isAssignableFrom(type)){
				return (T) new Float(value.toString());
			}else if(byte.class.isAssignableFrom(type)){
				return (T) new Byte(value.toString());
			}
			if(java.util.Date.class.isAssignableFrom(type)){
				try{
					return (T) DateUtil.StringToDate(value);
				}catch(ParseException ex){
					throw new NotSupportedTypeException("This value "+value+" is not a type of date!");
				}
			}
			if(java.util.List.class.isAssignableFrom(type)){
				String[] values = value.split(",");
				java.util.List<String> temp = new java.util.ArrayList<String>(values.length);
				for(int i=0; i<values.length; i++){
					temp.add(values[i]);
				}
				return (T) temp;
			}
			if(Map.class.isAssignableFrom(type)){
				String[] values = value.split(",");
				java.util.Map<String,String> temp = new java.util.HashMap<String,String>(values.length);
				for(int i=0; i<values.length; i++){
					String keyAndValue = values[i];
					if(keyAndValue.indexOf("=")!= -1){
						String[] spt = keyAndValue.split("=");
						temp.put(spt[0], spt[1]);
					}else if(keyAndValue.indexOf(":")!= -1){
						String[] spt = keyAndValue.split(":");
						temp.put(spt[0], spt[1]);
					}else{
						throw new NotSupportedTypeException("This value "+value+" is not a type of map!");
					}
				}
				return (T) temp;
			}
		}
		return (T) value;
	}
	
}
